<chapter xml:id="utf16.reader.h">
<title><tt>__vic/utf16/reader.h</tt></title>

<chapter xml:id="utf16--reader">
<title><tt>utf16::reader</tt></title>

<code-block lang="C++"><![CDATA[
template<class CodeUnitReader>
class utf16::reader
{
public:
    using code_unit_reader_type = CodeUnitReader;
    CodeUnitReader &get_code_unit_reader();
    const CodeUnitReader &get_code_unit_reader() const;

    template<class... Args>
    explicit reader(Args&&... args);  // since C++11

    reader(); // C++98 only
    explicit reader(CodeUnitReader r); // C++98 only

    utf16::read_result parse();
    sread_result<unicode_t> read();
    sread_result<unicode_t> operator()();
};

template<class CodeUnitReader>
utf16::reader<CodeUnitReader> utf16::make_reader(CodeUnitReader r);
]]></code-block>

<p>Вычитывает UTF-16 code points из последовательности 2-байтовых
<xref to="utf16--code_unit_t"/>. Последовательность читается посредством
специального reader, имеющего следующую структуру:</p>

<code-block lang="C++"><![CDATA[
class ]]><nt>CodeUnitReader</nt><![CDATA[
{
public:
    utf16::read_unit_result operator()();
};
]]></code-block>

<synopsis>
<prototype>utf16::read_unit_result operator()()</prototype>
<p>Пытается вычитать следующий code unit. Возвращает code unit, в случае
успеха, <tt>utf16::status::eof</tt>, если больше не осталось code units,
либо <tt>utf16::status::truncated_code_unit</tt> если доступна только часть
code unit.</p>
</synopsis>

<section><title>Члены класса</title>

<synopsis>
<prototype>CodeUnitReader &amp;get_code_unit_reader()</prototype>
<prototype>const CodeUnitReader &amp;get_code_unit_reader() const</prototype>
<p>Возвращает ссылку на используемый code unit reader.</p>
</synopsis>

<synopsis>
<prototype>template&lt;class... Args>
explicit reader(Args&amp;&amp;... args) <badge>C++11</badge></prototype>
<p>Передаёт все параметры в используемый code unit reader.</p>
</synopsis>

<synopsis>
<prototype>reader() <badge>C++98 only</badge></prototype>
<prototype>explicit reader(CodeUnitReader r) <badge>C++98 only</badge></prototype>
<p>Конструкторы для режима C++98.</p>
</synopsis>

<synopsis>
<prototype>utf16::read_result parse()</prototype>
<p>Пытается извлечь следующий code point из последовательности code unit,
используя <tt>CodeUnitReader</tt>. В случае успеха возвращается
прочитанный code point. Если code units кончились, возвращается
<tt>utf16::status::eof</tt>. Другие значения возвращаются в случае ошибок,
подробности см. в <xref to="utf16--status"/>. Для доступа к отдельным code
units используется <tt>CodeUnitReader::operator()</tt>.</p>
<note>Функция сама по себе не бросает исключений, но их может бросать
<tt>CodeUnitReader::operator()</tt>.</note>
</synopsis>

<synopsis>
<prototype>sread_result&lt;unicode_t> read()</prototype>
<prototype>sread_result&lt;unicode_t> operator()()</prototype>
<p>То же самое, что <tt>parse()</tt>, но возвращает <tt>sread_result</tt> в
случае успеха или при достижении конца файла. Бросает исключения из
<xref to="utf16.exceptions.h"/> в остальных случаях.</p>
</synopsis>

</section>

<section><title>Свободные функции</title>

<synopsis>
<prototype>template&lt;class CodeUnitReader>
utf16::reader&lt;CodeUnitReader> utf16::make_reader(CodeUnitReader r)</prototype>
<p>Создаёт UTF-16 reader используя указанный <tt>CodeUnitReader</tt>.</p>
</synopsis>

</section>

<section><title>Пример</title>
<code-block lang="C++"><![CDATA[
#include<__vic/utf16/reader.h>
#include<__vic/sreaders/string.h>
#include<string>
#include<cstdint>
#include<iostream>

class u16string_code_unit_reader
{
    __vic::basic_string_sreader<char16_t> r;
public:
    explicit u16string_code_unit_reader(const std::u16string &s) : r(s) {}

    __vic::utf16::read_unit_result operator()()
    {
        if(__vic::sread_result<__vic::utf16::code_unit_t> u = r())
            return u.value();
        return __vic::utf16::status::eof;
    }
};

void print_utf16_code_points(const std::u16string &s)
{
    __vic::utf16::reader<u16string_code_unit_reader> r(s);
    __vic::unicode_t cp;
    while(__VIC_SREAD_RESULT(unicode_t) cp = r())
        std::cout << uint_least32_t(cp.value()) << '\n';
}
]]></code-block>
</section>

</chapter>

</chapter>
